﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Diploma.Models.IRepositories;
using Diploma.Utils;

namespace Diploma.Models.Repositories
{
    internal class CollaborationRoomRepository : ICollaborationRoomRepository
    {
        private readonly DiplomaEntities dataContext;

        public CollaborationRoomRepository(DiplomaEntities datacontext)
        {
            dataContext = datacontext;
        }

        public CollaborationRoom GetCollaborationRoom(Guid id)
        {
            return dataContext.CollaborationRooms.Where(r => r.CollaborationRoomId == id).FirstOrDefault();
        }

        public void Add(CollaborationRoom room)
        {
            Guid newGuid = Guid.NewGuid();
            room.CollaborationRoomId = newGuid;
            room.DateAdd = DateTime.Now;
            dataContext.AddToCollaborationRooms(room);
            dataContext.SaveChanges();
            Directory.CreateDirectory(ConstantsUtil.GetRoomDirectoryPath(PathType.Absolute) + newGuid.ToString());
        }

        public void Edit(CollaborationRoom room)
        {
            CollaborationRoom oldRoom =
                dataContext.CollaborationRooms.FirstOrDefault(r => r.CollaborationRoomId == room.CollaborationRoomId);
            if (oldRoom == null)
                throw new Exception("No existing room for updating!");
            oldRoom.BaseDescription = room.BaseDescription;
            oldRoom.BaseTheme = room.BaseTheme;
            oldRoom.ConsultantId = room.ConsultantId;

            dataContext.SaveChanges();
        }

        public bool Delete(Guid id)
        {
            CollaborationRoom room =
                dataContext.CollaborationRooms.Where(r => r.CollaborationRoomId == id).FirstOrDefault();
            if (room == null)
                return false;
            room.MarkForDeletion();
            dataContext.SaveChanges();

            return true;
        }

        public void Refuse(Student student)
        {
            student.CollaborationPropos = null;
            dataContext.SaveChanges();
        }

        public void Participate(CollaborationRoom room, Student student, string newTheme, string newDescription)
        {
            if (student.CollaborationPropos != null && student.CollaborationPropos.DeletionDate == null)
                return;
            if (room == null)
                throw new Exception();

            var propose = new CollaborationPropose
                              {
                                  Student = student,
                                  IsApproved = false,
                                  CollaborationRoom = room,
                                  DateTime = DateTime.Now,
                                  Theme = newTheme,
                                  Description = newDescription,
                              };     

            dataContext.SaveChanges();
        }

        public void Participate(CollaborationRoom room, Student student)
        {
            Participate(room, student, null, null);
        }

        public void Approve(CollaborationRoom room, Student student)
        {
            CollaborationPropose propose =
                room.CollaborationProposes.Where(p => p.Student.UserId == student.UserId && p.DeletionDate == null).
                    FirstOrDefault();
            if (propose == null)
                throw new Exception();
            propose.IsApproved = true;
            propose.DateApproved = DateTime.Now;

            foreach (
                CollaborationPropose v in
                    room.CollaborationProposes.Where(p => p.Student.UserId != student.UserId && p.DeletionDate == null))
            {
                v.MarkForDeletion();
            }

            room.BaseTheme = propose.Theme ?? room.BaseTheme;
            room.BaseDescription = propose.Description ?? room.BaseDescription;

            dataContext.SaveChanges();
        }

        public IEnumerable<Message> GetMessages(CollaborationRoom room)
        {
            return room.Messages.Where(m => m.DeletionDate == null).OrderByDescending(m => m.PubDate);
        }

        public IEnumerable<Task> GetTasks(CollaborationRoom room)
        {
            return room.Tasks.Where(t => t.DeletionDate == null);
        }

        public void UpdatePracticePlace(Guid id, Guid companyId)
        {
            var room = GetCollaborationRoom(id);
            room.PracticePlace = companyId;

            dataContext.SaveChanges();
        }
    }
}